<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <title>Web Bluetooth 中心端示例</title>
  <style>
    body { font-family: system-ui, Arial, sans-serif; max-width: 840px; margin: 24px auto; }
    #log { border: 1px solid #ccc; padding: 8px; height: 240px; overflow: auto; white-space: pre-wrap; background: #fafafa; }
    input, button { margin: 6px 4px; padding: 6px 10px; }
    .row { margin: 8px 0; }
  </style>
</head>
<body>
  <h1>Web Bluetooth 中心端示例</h1>
  <p>服务 UUID：<code>0000ffff-0000-1000-8000-00805f9b34fb</code></p>
  <p>写入特征：<code>0000ff01-0000-1000-8000-00805f9b34fb</code>；通知特征：<code>0000ff02-0000-1000-8000-00805f9b34fb</code></p>

  <div class="row">
    <label><input type="radio" name="scanMode" value="service" checked> 服务过滤（更精准）</label>
    <label style="margin-left:8px;"><input type="radio" name="scanMode" value="compatible"> 兼容模式（acceptAllDevices）</label>
  </div>
  <div class="row">
    <button id="btnConnect">连接设备</button>
    <button id="btnDisconnect">断开</button>
  </div>
  <div class="row">
    <input id="text" placeholder="输入要发送的文本" />
    <button id="btnSend">发送到 FF01</button>
  </div>

  <h3>日志</h3>
  <div id="log"></div>

<script>
const SERVICE_UUID = '0000ffff-0000-1000-8000-00805f9b34fb';
const WRITE_CHAR_UUID = '0000ff01-0000-1000-8000-00805f9b34fb';
const NOTIFY_CHAR_UUID = '0000ff02-0000-1000-8000-00805f9b34fb';

let device, server, service, writeChar, notifyChar;
const log = (...args) => { const d = document.getElementById('log'); d.textContent += args.join(' ') + '\n'; d.scrollTop = d.scrollHeight; };

async function connect() {
  try {
    log('请求设备…');
    // 通过服务过滤更精准；若发现不到设备，可改用 acceptAllDevices
    const mode = document.querySelector('input[name="scanMode"]:checked')?.value || 'service';
    const options = mode === 'service'
      ? { filters: [{ services: [SERVICE_UUID] }], optionalServices: [SERVICE_UUID] }
      : { acceptAllDevices: true, optionalServices: [SERVICE_UUID] };
    device = await navigator.bluetooth.requestDevice(options);
    device.addEventListener('gattserverdisconnected', () => log('设备已断开'));

    log('连接 GATT…');
    server = await device.gatt.connect();
    service = await server.getPrimaryService(SERVICE_UUID);

    writeChar = await service.getCharacteristic(WRITE_CHAR_UUID);
    notifyChar = await service.getCharacteristic(NOTIFY_CHAR_UUID);

    log('订阅通知…');
    await notifyChar.startNotifications();
    notifyChar.addEventListener('characteristicvaluechanged', (ev) => {
      const v = ev.target.value; // DataView
      const bytes = new Uint8Array(v.buffer);
      const text = new TextDecoder().decode(bytes);
      log('收到通知：', text, '（', Array.from(bytes).join(','), '）');
    });

    log('连接完成，可发送文本到 FF01');
  } catch (e) {
    log('连接失败：', e);
  }
}

async function send() {
  try {
    if (!writeChar) return log('尚未连接');
    const text = document.getElementById('text').value || '';
    const data = new TextEncoder().encode(text);
    await writeChar.writeValue(data);
    log('已写入 FF01：', text);
  } catch (e) {
    log('写入失败：', e);
  }
}

function disconnect() {
  try {
    if (device && device.gatt.connected) device.gatt.disconnect();
    log('主动断开');
  } catch (e) {
    log('断开异常：', e);
  }
}

document.getElementById('btnConnect').onclick = connect;
document.getElementById('btnSend').onclick = send;
document.getElementById('btnDisconnect').onclick = disconnect;
</script>
</body>
</html>